package com.niiwoo.civet.trade.dao.mapper;

import com.niiwoo.civet.trade.dao.entity.Project;
import com.niiwoo.civet.trade.dao.entity.ProjectInvesting;
import com.niiwoo.civet.trade.dto.UserSuccessProjectCountDTO;
import com.niiwoo.civet.trade.dto.request.myloan.InvestingProjectPageRequestDTO;
import com.niiwoo.civet.trade.dto.response.myloan.LoanEndResponseDTO;
import com.niiwoo.civet.trade.dto.response.myloan.UserProjectStatisticResponseDTO;
import com.niiwoo.civet.trade.enums.ProjectFromSourceEnum;
import com.niiwoo.civet.trade.enums.ProjectStatusEnum;
import com.niiwoo.civet.trade.enums.ProjectSubStatusEnum;
import com.niiwoo.civet.trade.enums.ProjectTypeEnum;
import com.niiwoo.civet.trade.service.local.statisticsinfo.ProjectForTianyan;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
public interface ProjectMapperExt extends ProjectMapper {

    Project selectByPrimaryKeyForUpdate(Long projectId);

    /**
     * 根据用户标的状态统计借款金额
     * @param userId
     * @param statusList
     * @return
     */
    BigDecimal statisticsLoanAmountByStatus(@Param("userId") String userId, @Param("statusList") List<Byte> statusList, @Param("subStatusList") List<Integer> subStatusList, @Param("type") Byte type);

    /**
     * 根据用户标的状态统计标的数量
     * @param userId
     * @param statusList
     * @param subStatusList
     * @return
     */
    int statisticsProjectCountByStatus( @Param("userId") String userId, @Param("statusList") List<Byte> statusList, @Param("subStatusList") List<Integer> subStatusList);

    /**
     * 根据用户标的单状态统计标的数量
     * @param userId
     * @param status
     * @param subStatus
     * @return
     */
    int statisticsProjectCountBySingleStatus( @Param("userId") String userId, @Param("status") Byte status, @Param("subStatus") Integer subStatus);


    /**
     * 查询用户已经结清的标
     * @param userId
     * @return
     */
    List<Project> queryProjectByUserId(@Param("userId") String userId);

    /**
     * 我的借款查询-已结束 总记录数
     * @param userId
     * @return
     */
    int selectMyloanEndedCount(String userId);

    /**
     * 我的借款查询-已结束
     * @param userId
     * @return
     */
    List<LoanEndResponseDTO> selectMyloanEndeds(@Param("userId") String userId, @Param("start") Integer start, @Param("end") Integer end);

    /**
     * 查询用户退回状态的标的
     * @param userId
     * @return
     */
    Project speedLoanQueryForBack(@Param("userId") String userId);

	List<Project> queryProjectListByProjectIds(List<Long> list);

    /**
     * 查询标的信息
     * @param userId
     * @param projectId
     * @return
     */
    Project selectByUserIdAndProjectId(@Param("userId") String userId, @Param("projectId") Long projectId);

    /**
     * 查询成功借款金额,成功借款笔数
     * @param userId
     * @return
     */
    UserProjectStatisticResponseDTO selectSuccessAmount(@Param("userId") String userId);

    /**
     * 结清借款笔数
     * @param userId
     * @return
     */
    Integer selectFinishCount(@Param("userId") String userId);

    /**
     * 逾期当前借款笔数
     *
     * @param userId
     * @return
     */
    Integer selectOverdueCount(@Param("userId") String userId);

    List<Project> selectListByProjectIdSet(List<Long> list);

    /**
     * 审核中借款笔数
     * @param userId
     * @return
     */
    Integer queryProjectInApprove(@Param("userId") String userId);

    /**
     * 未结清借款笔数
     * @param userId
     * @return
     */
    Integer queryProjectNotSettled(@Param("userId") String userId);

    /**
     * 查询用户审核通过的标的数量
     * @param userId
     * @return
     */
    Integer selectAuditPassProjectCount(String userId);

    /**
     * 查询用户最近一个标的
     * @param userId
     * @return
     */
    Project selectLastOneByUserId(String userId);

    /**
     * 查询用户最近一个融360标的
     * @param userId
     * @return
     */
    Project selectLastR360ByUserId(String userId);

    /**
     * 查询用户审核中标的数量,限定标的来源
     * @param userId
     * @param fromSource
     * @return
     */
    Integer queryProjectInApproveWithFromSource(@Param("userId") String userId, @Param("fromSource") int fromSource);

    /**
     * 查询用户未结清标的数量,限定标的来源
     * @param userId
     * @param fromSource
     * @return
     */
    Integer queryProjectNotSettledWithFromSource(@Param("userId") String userId, @Param("fromSource") int fromSource);


    /**
     * 查询用户的所有标的
     * @param userId
     * @param subStatus
     * @return
     */
    List<Project> queryAllProjectByUserId(@Param("userId") String userId, @Param("subStatus") List<Integer> subStatus);


    int updateByUserIdProjectSelective(Project record);

    /**
     * 退回标的更新
     * @param record
     * @return
     */
    int updateForBackProject(Project record);

	List<UserSuccessProjectCountDTO> selectUserSuccessProjectCountDTOList(List<String> list);

    /**
     * 根据标的状态统计借款金额
     * @param statusList
     * @param subStatusList
     * @return
     */
    BigDecimal statisticsLoanAmountByStatusAndSubStatus(@Param("statusList") List<ProjectStatusEnum> statusList, @Param("subStatusList") List<ProjectSubStatusEnum> subStatusList);

    Project selectProjectByUserIdProjectId(@Param("userId") String userId,@Param("projectId") Long projectId);

    /**
     * 查询指定时间前在审核状态的标
     * @return
     */
    List<Project> queryAuthNotifyAuditProjectList(@Param("endDate")Date endDate);
    
    /**
     * 查询R360审核通过未确认的标的列表
     * 
     * @param timeout
     * 				超时未确认
     * @return
     */
	List<Project> selectR360TimeoutUnconfirmedProjectList(@Param("timeout") Integer timeout);

	List<Project> selectListOverInvestEndTime();

    /**
     * 查询退回超时需要流标标的列表
     * @param timeoutDeadline
     * @return
     */
    List<Project> selectReturnTimeoutProjectList(@Param("timeoutDeadline") Integer timeoutDeadline);

    /**
     * @param userId
     * @param fromSource
     * @return
     */
    Integer queryProjectNumInApproveAndInvestWithSource(@Param("userId") String userId, @Param("fromSource") ProjectFromSourceEnum fromSource);

    List<Project> listProjectByChannelCodeAndStatus( @Param("userId") String userId, @Param("channelCode") String channelCode, @Param("statusList") List<ProjectStatusEnum> statusList, @Param("subStatusList") List<ProjectSubStatusEnum> subStatusList);

    /**
     * 查询审核中的借款笔数
     * @return userId
     */
    Integer selectInAuditProjectCount(String userId);

    /**
     * 查询提交借款笔数
     * @return userId
     */
    Integer selectProjectCountByUserIdAndOrgId(@Param("userId")String userId,@Param("orgId")String orgId);

    Integer selectProjectCountByUserId(@Param("userId")String userId);

    /**
     * 查询用户借款中的标的数量
     * @param userId
     * @return
     */
    Integer selectLoaningProjectCount(@Param("userId")String userId);

    /**
     * 查询用户成功借款次数
     * @param userId
     * @return
     */
    Integer selectLoanSuccessCount(@Param("userId")String userId);

    /**
     * 查询符合状态条件的标的
     * @param userId
     * @param subStatus
     * @return
     */
    Integer findProjectByStatus(@Param("userId") String userId,@Param("list") List<Byte> subStatus);

    /**
     * 查询用户是否为复借用户（除去极速借机构）
     * @param userId
     * @param statusList
     * @return
     */
    Integer querySuccProjectByStatus(@Param("userId") String userId, @Param("statusList") List<Byte> statusList);

    /**
     * 查询用户指定状态的标的个数
     * @param userId
     * @param subStatus
     * @return
     */
    Integer selectProjectCountBySubStatus(@Param("userId") String userId,@Param("list") List<Integer> subStatus);

    Integer selectCountNoContainTypeEnum(@Param("userId") String userId, @Param("projectTypeEnum") ProjectTypeEnum projectTypeEnum, @Param("statusEnumList") List<ProjectStatusEnum> statusEnumList);

    Project selectNewestProject(@Param("userId") String userId, @Param("statusEnumList") List<ProjectStatusEnum> statusEnumList);
    /**
     * 查询未签署代扣协议的用户项目信息
     * @param status
     * @param channelCode
     * @param userIdList
     * @return
     */
    List<Project> queryUserSignConstract(@Param("status")byte status,@Param("channelCode")String channelCode,
                                   @Param("list") List<String> userIdList);

    /**
     * 查询符合项目状态的标的
     * @param userId
     * @param statusEnumList
     * @return
     */
    Integer queryProjectByStatus(@Param("userId") String userId,@Param("statusEnumList") List<ProjectStatusEnum> statusEnumList);

    /**
     * 根据用户与标的状态统计借款金额
     *
     * @param borrowUserId
     * @param status
     * @return
     */
    BigDecimal countAmountByUserIdAndStatus(@Param("borrowUserId") String borrowUserId, @Param("status") Byte status);

    /**
     * 统计逾期指定天数的标的个数（包含结清的与还款中的）
     * @param borrowUserId
     * @param exceedDay
     * @return
     */
    Integer statisticsUserOverdueExceedDay(@Param("borrowUserId") String borrowUserId, @Param("exceedDay") Integer exceedDay);

    /**
     * 统计用户进行中的标的
     *
     * @param borrowerUserId
     * @return
     */
    Integer selectMyloanGoingCount(@Param("borrowUserId") String borrowUserId);

    /**
     * 分页查询用户进行中的标的
     *
     * @param borrowerUserId
     * @param start
     * @param end
     * @return
     */
    List<Project> selectMyloanGoings(@Param("borrowUserId") String borrowUserId, @Param("start") Integer start, @Param("end") Integer end);

    /**
     * 统计今日审核通过的标的数量
     *
     * @param startDate
     * @param endDate
     * @return
     */
    Integer countTodayAuditPassProject(@Param("startDate") Date startDate,@Param("endDate") Date endDate);

    List<Project> selectListByOverDate(@Param("projectTypeEnum") ProjectTypeEnum projectTypeEnum, @Param("subStatusEnumList") List<ProjectSubStatusEnum> subStatusEnumList,@Param("overDate") Date overDate);

    /**
     * 统计系统重构上线(2018-03-31)前发布且当前未结清的标的
     * @param userId
     * @return
     */
    List<Project> selectUnfinishedProjectBeforeSystemRebuildOnline(String userId);

    /**
     * 统计系统重构上线(2018-03-31)后发布的标的数量
     * @param userId
     * @return
     */
    Integer countProjectAfterSystemRebuildOnline(String userId);

    Byte selectTeProjectFlag(@Param("borrowUserId") String borrowUserId, @Param("projectId") Long projectId);

    /**
     * 查询未结清借款笔数(不包含机构极速借)
     * @param userId
     * @return
     */
    Integer selectOutstandingProjectWithoutOrg(@Param("userId") String userId);

    /**
     * 通过用户ID和机构ID查询还款中的标的列表
     * @param userId
     * @param orgId
     * @return
     */
    List<Project> selectProjectByUserIdAndOrgId(@Param("userId")String userId, @Param("orgId")String orgId);
    /**
     * 根据期限查询最后一次满标的
     * @param dateUnit
     * @param deadLine
     * @return
     */
	Project selectLastByDeadline(@Param("dateUnit")Byte dateUnit, @Param("deadLine")Integer deadLine, @Param("orgId") String orgId,@Param("repaymentType") Byte repaymentType);

    /**
     * 分页查询列表
     * @param investingProjectPageRequestDTO
     * @return
     */
    List<ProjectInvesting> selectPageByParamsByProject(@Param("params") InvestingProjectPageRequestDTO investingProjectPageRequestDTO);

    /**
     * 分页查询数量
     * @param investingProjectPageRequestDTO
     * @return
     */
    Integer selectPageByParamsByProjectCount(@Param("params") InvestingProjectPageRequestDTO investingProjectPageRequestDTO);

    Project selectLastFullTime();

    List<Project> selectFullProjectByDate(@Param("startTime") Date startTime,@Param("endTime") Date endTime,@Param("start") Integer start,@Param("size") Integer size);
    List<Project> selectFullProjectByDateRepaying(@Param("startTime") Date startTime,@Param("endTime") Date endTime,@Param("start") Integer start,@Param("size") Integer size);

    Map<String,Object> countFullProjectByDate(@Param("startTime") Date startTime, @Param("endTime") Date endTime);
    Map<String,Object> countFullProjectByDateRepaying(@Param("startTime") Date startTime, @Param("endTime") Date endTime);

    List<Project> selectInvestingProjectByDate(@Param("startTime") Date startTime,@Param("endTime") Date endTime,@Param("start") Integer start,@Param("size") Integer size);

    Integer countInvestingProjectByDate(@Param("startTime") Date startTime,@Param("endTime") Date endTime);

    Integer countOverdebtProjects(@Param("startTime")Date startTime,@Param("endTime")Date endTime);
    List<ProjectForTianyan> selectOverdebtProjects(@Param("startTime")Date startTime, @Param("endTime")Date endTime, @Param("start")Integer start, @Param("size")Integer size);

    /**
     * 重置标的加息
     *
     * @param projectId
     * @return
     */
	int resetProjectRaiseRate(Long projectId);

    /**
     * 查询待打包的标的列表
     * (最近一个月提交申请分端到智能投/新手智能投投资中并且未打包的标的)
     * @return
     */
    List<Project> selectWaitingPackageProjectList();

    int resetInvestEndTime(@Param("projectId")Long projectId);
    /**
     * 查询标的申请来源
     * @param userId
     * @return
     */
    List<Byte> queryFromSourceListByUserId(@Param("userId")String userId);

    /**
     * 查询近一个月内未发生逾期且未发生过还款的标的
     * @param monthAgoDate
     * @param today
     * @return
     */
    List<Project> selectAllProjectOverdueWithoutReport(@Param("monthAgoDate") Date monthAgoDate,@Param("today") Date today,@Param("isFirstMonth")Byte isFirstMonth,@Param("isLimit")Byte isLimit);

    /**
     * 查询需要补偿调用天称信审要点记录
     * @return
     */
    List<Project> selectNeedRecallAutoAuditModelRecord();
}